# gozerbot/udp.py
#
#

""" implement listenudp thread """

__copyright__ = 'this file is in the public domain'

from gozerbot.generic import rlog, handle_exception
from gozerbot.config import config
import socket, re, time

def listenudp(bot):
    """ listen for udp messages """
    if not config['udp']:
        rlog(1, 'udp', 'udp not enabled')
        return
    # create and listen on UDP socket
    try:
        udpsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            udpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
        except:
            pass
        udpsock.setblocking(1)
        udpsock.bind((config['udphost'], config['udpport']))
        rlog(10, 'udp', 'udp listening on %s %s' % (config['udphost'], \
config['udpport']))
        udprunning = 1
    except IOError:
        handle_exception()
        udpsock = None
        udprunning = 0
        return
    # loop on listening udp socket
    while(udprunning):
        try:
            if udpsock == None:
                break
            data, addr = udpsock.recvfrom(400)
        except IOError:
            handle_exception()
            udprunning = 0
            break
        if addr == None:
            udprunning = 0
            break
        # check if udp is enabled and source ip is in udpallow list
        if config['udp'] and addr[0] in config['udpallow']:
            # get printto and passwd data
            header = re.search('(\S+) (\S+) (.*)', data)
            if header:
                # check password
                if header.group(1) == config['udppassword']:
                    printto = header.group(2)    # is the nick/channel
                    # check if printto is in allowednicks
                    if not printto in config['udpallowednicks']:
                        continue
                    rlog(10, 'udp', str(addr[0]) +  " udp allowed")
                    text = header.group(3)    # is the text
                    time.sleep(3)
                    bot.say(printto, text)
                else:
                    rlog(10, 'udp', "can't match udppasswd from " + str(addr))
            else:
                rlog(10, 'udp', "can't match udp from " + str(addr[0]))
        else:
            rlog(10, 'udp', 'denied udp from ' + str(addr[0]))
    rlog(10, 'bot', 'stopping listenudp')
    udprunning = 0
    udpsock.shutdown(2)
    udpsock.close()
